<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <!-- Metas -->
    <title>curtains.js | Documentation | Scene rendering order</title>
    <meta name="description" content="curtains.js is a lightweight vanilla WebGL javascript library that turns HTML DOM elements into interactive textured planes.">
    <link rel="canonical" href="https://www.curtainsjs.com/migration-guide-to-v7.html">

    <!-- Facebook OG -->
    <meta property="og:title" content="curtains.js | Documentation | Scene rendering order">
    <meta property="og:type" content="website">
    <meta property="og:description" content="curtains.js is a lightweight vanilla WebGL javascript library that turns HTML DOM elements into interactive textured planes.">
    <meta property="og:url" content="https://www.curtainsjs.com/migration-guide-to-v7.html">
    <meta property="og:image" content="https://www.curtainsjs.com/images/curtains-js-logo.jpg">

    <!-- Twitter card -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@martinlaxenaire">
    <meta name="twitter:creator" content="@martinlaxenaire">
    <meta name="twitter:title" content="curtains.js | Documentation | Scene rendering order">
    <meta name="twitter:description" content="curtains.js is a lightweight vanilla WebGL javascript library that turns HTML DOM elements into interactive textured planes.">
    <meta name="twitter:image" content="https://www.curtainsjs.com/images/curtains-js-logo.jpg">

    <!-- Favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="images/favicons/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="images/favicons/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="images/favicons/favicon-16x16.png">
    <link rel="manifest" href="images/favicons/site.webmanifest">
    <link rel="mask-icon" href="images/favicons/safari-pinned-tab.svg" color="#202340">
    <link rel="shortcut icon" href="images/favicons/favicon.ico">
    <meta name="msapplication-TileColor" content="#202340">
    <meta name="msapplication-config" content="images/favicons/browserconfig.xml">
    <meta name="theme-color" content="#202340">

    <link href="https://fonts.googleapis.com/css?family=PT+Sans:400,700" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Abril+Fatface" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div id="page-wrap">

    <div id="canvas"></div>

    <div id="content">

        <header id="header">
            <div class="wrapper">
                <div id="header-wrapper" class="flex-wrapper">
                    <div id="header-title">
                        <a href="/" title="Home">curtains.js</a>
                    </div>
                    <nav id="main-menu">
                        <ul class="flex-wrapper">
                            <li>
                                <a href="get-started.html">Get started</a>
                            </li>
                            <li>
                                <a href="documentation.html" class="active">Docs</a>
                            </li>
                            <li>
                                <a href="download.html">Download</a>
                            </li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>

        <section class="content-section api-section">

            <nav id="api-menu-nav">

                <ul id="api-menu">
                    <li class="active">
                        <div class="api-top-menu-item">Core</div>
                        <ul class="api-submenu-content">
                            <li>
                                <a href="curtains-class.html">Curtains</a>
                            </li>
                            <li>
                                <a href="plane-class.html">Plane</a>
                            </li>
                            <li>
                                <a href="texture-class.html">Texture</a>
                            </li>
                        </ul>
                    </li>
                    <li class="active">
                        <div class="api-top-menu-item">Frame Buffer Objects</div>
                        <ul class="api-submenu-content">
                            <li>
                                <a href="render-target-class.html">RenderTarget</a>
                            </li>
                            <li>
                                <a href="shader-pass-class.html">ShaderPass</a>
                            </li>
                        </ul>
                    </li>
                    <li class="active">
                        <div class="api-top-menu-item">Loaders</div>
                        <ul class="api-submenu-content">
                            <li>
                                <a href="texture-loader-class.html">TextureLoader</a>
                            </li>
                        </ul>
                    </li>
                    <li class="active">
                        <div class="api-top-menu-item">Math</div>
                        <ul class="api-submenu-content">
                            <li>
                                <a href="vec-2-class.html">Vec2</a>
                            </li>
                            <li>
                                <a href="vec-3-class.html">Vec3</a>
                            </li>
                            <li>
                                <a href="mat-4-class.html">Mat4</a>
                            </li>
                            <li>
                                <a href="quat-class.html">Quat</a>
                            </li>
                        </ul>
                    </li>
                    <li class="active">
                        <div class="api-top-menu-item">Extras</div>
                        <ul class="api-submenu-content">
                            <li>
                                <a href="ping-pong-plane-class.html">PingPongPlane</a>
                            </li>
                            <li>
                                <a href="fxaa-pass-class.html">FXAAPass</a>
                            </li>
                        </ul>
                    </li>
                </ul>
            </nav>

            <div id="api-content">

                <div class="api-content-inner">
                    <div class="inner-section">
                        <h1>Scene rendering order</h1>

                        <p>
                            Since v7.3, the whole scene rendering order has been refactored. It ensures that all the planes will be rendered out of the box, no matter in what order they are added, but also allows for a better control over the planes render order.
                        </p>

                        <h2>How WebGL handles drawing and depth</h2>

                        <p>
                            First, you have to know that WebGL depth test means that the GPU will not execute a fragment shader for any pixels that would be behind other things. This means that given the same depth, objects that are added first are rendered on top of others (from front to back).<br />
                            See <a href="https://webgl2fundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html#drawing-transparent-things-and-multiple-lists" target="_blank" title="WebGL2 fundamentals: drawing multiple things">WebGL2 fundamentals: drawing multiple things</a> for more informations.
                        </p>

                        <h2>curtains.js drawing order</h2>

                        <p>
                            The order in which all the objects are drawn by curtains.js is managed by the Scene class (view <a href="https://github.com/martinlaxenaire/curtainsjs/blob/master/src/core/Scene.js" title="Scene class source code" target="_blank">source code</a>).<br />
                            It creates a bunch of stacks that contains the objects that will be drawn in a specific order.<br />
                            Those are the different draw calls and operations executed at each render:
                        </p>

                        <ol class="main-ordered-list">
                            <li>
                                <h3>PingPongPlane's stack</h3>
                                <p>
                                    First, the library draws all the <a href="ping-pong-plane-class.html">PingPongPlanes</a> that have been added, if any.<br />
                                    This ensures that whatever the other planes and shader passes your scene contains, the PingPongPlanes will be correctly rendered.
                                </p>
                            </li>

                            <li>
                                <h3>RenderTarget's stack</h3>
                                <p>
                                    The library will then draw all the planes that are attached to a <a href="render-target">RenderTarget</a>:
                                </p>
                                <ul class="internal-classes-list">
                                    <li>
                                        It will start by drawing the planes from the first render target created, if any, ordered by their renderOrder property, then indexes (first added first drawn).
                                    </li>
                                    <li>
                                        Then it will draw the planes from the second render target created, if any, following the same order.
                                    </li>
                                    <li>
                                        Repeat for all the render targets that have been created...
                                    </li>
                                </ul>
                            </li>

                            <li>
                                <h3>Draw the render targets' shader passes</h3>
                                <p>
                                    The library will then draw those render targets' shader passes content, which means all the <a href="shader-pass-class.html">ShaderPasses</a> that have been created by passing a renderTarget as parameter. They will be drawn ordered by their renderOrder property (from lower to higher), then indexes (first added first drawn).<br />
                                    To be sure everything remains visible, the WebGL context depth buffer is cleared after each pass has been drawn.
                                </p>
                            </li>

                            <li>
                                <h3>Opaque's stack</h3>
                                <p>
                                    Then it will draw all the planes that have their transparent property set to false.<br />
                                    They are ordered by their renderOrder property, geometry IDs and then indexes (first added first drawn).
                                </p>
                            </li>

                            <li>
                                <h3>Transparent's stack</h3>
                                <p>
                                    Then it will enable blending and draw all the planes that have their transparent property set to true.<br />
                                    They are ordered by their renderOrder property, their translation along Z axis, geometry IDs and then indexes (first added first drawn).
                                </p>
                            </li>

                            <li>
                                <h3>Draw the scene shader passes</h3>
                                <p>
                                    Finally it will draw the scene's shader passes content (post processing), which means all the <a href="shader-pass-class.html">ShaderPasses</a> that have been created without passing any renderTarget as parameter. They will be drawn ordered by their renderOrder property (from lower to higher), then indexes (first added first drawn).
                                </p>
                            </li>
                        </ol>

                    </div>
                </div>
            </div>

        </section>
    </div>
</div>

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-141413267-1"></script>
<script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', 'UA-141413267-1');
</script>

</body>
</html>
